#include "CFileTest.h"
#include "./zip/qzipreader_p.h"
#include "./zip/qzipwriter_p.h"

CFileTest::~CFileTest()
{
    QDir dir(getTmpPath());
    removeDir(dir);
}

int CFileTest::removeDir(QDir & dir)
{
    int res = 0;
    //Получаем список каталогов
    QStringList lstDirs = dir.entryList(QDir::Dirs |
		  QDir::AllDirs |
		  QDir::NoDotAndDotDot);
    //Получаем список файлов
    QStringList lstFiles = dir.entryList(QDir::Files);

    //Удаляем файлы
    foreach (QString entry, lstFiles)
    {
	QString entryAbsPath = dir.absolutePath() + "/" + entry;
	QFile::setPermissions(entryAbsPath, QFile::ReadOwner | QFile::WriteOwner);
	QFile::remove(entryAbsPath);
    }

    //Для папок делаем рекурсивный вызов
    foreach (QString entry, lstDirs)
    {
	QString entryAbsPath = dir.absolutePath() + "/" + entry;
	QDir dr(entryAbsPath);
	removeDir(dr);
    }

    //Удаляем обрабатываемую папку
    if (!QDir().rmdir(dir.absolutePath()))
    {
	res = 1;
    }
    return res;
}

QDomDocument CFileTest::loadT2PFile(QString t2pFileName)
{
    this->t2pFile = t2pFileName;
    fileIsOpen = true;
    if (!extractT2PFile(t2pFileName))
	return QDomDocument();

    QFile file;
    QDomDocument domDocument;
    file.setFileName(this->t2pDir+"/tests/tests.xml");
    if (file.open(QIODevice::ReadOnly)) //Открываем файл
    {
	//Меняем src для картинок с %_IMG_SRC_%/ на реальный путь в распакованном каталоге
	QByteArray byteArray = file.readAll();
	byteArray.replace(QByteArray("%_IMG_SRC_%/"), QByteArray((this->t2pDir+"/tests/img/").toAscii().data()));
	if (domDocument.setContent(byteArray))//Получаем содержимое файла
	{
	    file.close();
	    return domDocument;
	}
	file.close();
    }
    emit this->fileOpened(t2pFileName);
    return QDomDocument();
}

bool CFileTest::saveFile(QString t2pFileName, QDomDocument domDocument)
{
    this->t2pFile = t2pFileName;
    if (t2pFile=="") return false;
    QFile file(t2pDir + "/tests/tests.xml");
    //Открываем файл для перезаписи
    if (file.open(QIODevice::WriteOnly|QIODevice::Truncate))
    {
	//Если файл открывали ранее, то просто заливаем DOM-модель документа в файл
	if (fileIsOpen)
	{
	    QByteArray byteArray;
	    QTextStream stream(&byteArray, QIODevice::ReadWrite);
            stream.setCodec("UTF-8");
	    domDocument.save(stream, 1, QDomNode::EncodingFromTextStream);
            byteArray.replace(QByteArray((this->t2pDir+"/tests/img/").toUtf8().data()), QByteArray("%_IMG_SRC_%/"));
            QTextStream(&file) << byteArray;
	}
	file.close();
	this->compress(t2pFile, t2pDir+"/tests/");
    }
    return true;
}

QDomDocument CFileTest::newFile()
{
    //создаем DOM-модель документа
    //QDomDocument doc("Test");
    QDomDocument doc("Data");
//    QDomElement domElement = doc.createElement("Tests");
    QDomProcessingInstruction instr = doc.createProcessingInstruction("xml","version='1.0' encoding='UTF-8'");
    doc.appendChild(instr);
    //doc.appendChild(domElement);
    QDomElement data = doc.createElement("Data");
    data.appendChild(doc.createElement("Tests"));
    data.appendChild(doc.createElement("Settings"));
    data.firstChildElement("Settings").appendChild(doc.createElement("printSettings"));
    data.firstChildElement("Settings").appendChild(doc.createElement("pageSettings"));
    doc.appendChild(data);
    //Создаем временный каталог
    QDir tmpDir;
    QVariant time = QDateTime::currentMSecsSinceEpoch();
    if (!tmpDir.mkpath(QDir::tempPath()+"/"+"tests."+time.toString()))
        return QDomDocument();
    tmpDir.mkpath(QDir::tempPath()+"/"+"tests."+time.toString()+"/tests");
    tmpDir.mkpath(QDir::tempPath()+"/"+"tests."+time.toString()+"/tests/Img");
    this->fileIsOpen = true;
    this->t2pDir = QDir::tempPath()+"/"+"tests."+time.toString();
    return doc;
}

bool CFileTest::extractT2PFile(QString t2pFileName)
/*
    1. Подготовка директории для распаковки t2p-файла
    2. Вызов функции для распаковки файла в созданную директорию
*/
{
    //Создаем временный каталог для распаковки файла
    QDir tmpDir;
    //возвращает число миллсекунд прошедших с начала эпохи
    //необходима для генерации уникального имени директории для распаковки архива
    QVariant time = QDateTime::currentMSecsSinceEpoch();
    //создаем каталог типа /tmp/tests.1300636368481 и запоминаем его полный путь
    if (!tmpDir.mkpath(QDir::tempPath()+"/"+"tests."+time.toString()))
	return false;
    this->t2pDir = QDir::tempPath()+"/"+"tests."+time.toString();

    if (!decompress(t2pFileName, this->t2pDir))
	return false;

    return true;
}

/*
 * Метод архивирует каталог dir в архив zip
 */
bool CFileTest::compress(const QString& zip, const QString& dir)
{
    //Создаем архив
    QZIP::QZipWriter zipWriter(zip);
    zipWriter.addDirectory("tests");
    zipWriter.addDirectory("tests/img");
    QFile xmlFile(dir+"/tests.xml");
    QByteArray xmlFileBA;
    if (xmlFile.exists() && xmlFile.open(QIODevice::ReadOnly))
    {
	xmlFileBA = xmlFile.readAll();
	zipWriter.addFile("tests/tests.xml", xmlFileBA);
    }
    else
	return false;
    xmlFile.close();

    QByteArray buf;
    //Получаем список файлов в диркетории img
    QString pathForImg = dir+"img";
    QDir tmpDir(pathForImg);
    QStringList lstFiles = tmpDir.entryList(QDir::Files | QDir::NoDotAndDotDot);
    //Пакуем только те, на которые есть ссылка в xml-документе
    QFile file;
    foreach (QString entry, lstFiles)
    {
	QString entryAbsPath = tmpDir.absolutePath() + "/" + entry;
	file.setFileName(entryAbsPath);
	if (xmlFileBA.indexOf(entry) != -1)
	{
	    if (file.exists() && file.open(QIODevice::ReadOnly))
	    {
		buf = file.readAll();
		QFileInfo fileInfo(file);
		QString fileName = fileInfo.fileName();
		qDebug()<<fileName;
		zipWriter.addFile("tests/img/"+fileName, buf);
	    }
	    file.close();
	}
	else
	    file.remove();
    }
    file.close();
    xmlFile.close();
    zipWriter.close();
    return true;
}

/*
 *Метод разархивирует зип-файл file в каталог dir
 */
bool CFileTest::decompress(const QString& file, const QString& dir)
{
    if (!QFile::exists(file))
    {
	qDebug() << "File does not exist.";
	return false;
    }

    QZIP::QZipReader unzip(file,QIODevice::ReadOnly);
    if (!unzip.extractAll(dir))
    {
	qDebug()<<"CFileTest::decompress : Cann't open t2p file";
	return false;
    }
    unzip.close();
    return true;

}

QString CFileTest::getTmpPath()
{
    return this->t2pDir;
}

QString CFileTest::addImage(QString &file)
{
    if (file.isEmpty())
    {
	return QString();
    }
    QFile f(file);
    QString name;

    if (f.exists())
    {
	QFileInfo fi(file);
	name = fi.fileName();
	QVariant time = QDateTime::currentMSecsSinceEpoch();
	name.prepend(this->getTmpPath()+"/tests/img/"+time.toString());
	f.copy(name);
    }
    else return QString();
    qDebug()<<name;
    return name;
}
